package JUC.第02章_Future;

import java.util.concurrent.*;

/**
 * 使用Future之前提供的那点API就囊中羞涩，处理起来不够优雅，
 * 这时候还是让CompletableFuture以声明式的方式优雅的处理这些需求
 *
 * 阻塞的方式和异步编程的设计理念相违背，而轮询的方式会耗费无谓的CPU资源。
 * 因此，JDK8设计出CompletableFuture。
 * CompletableFuture提供了一种观察者模式类似的机制，可以让任务执待完成后通知监听的一方。
 *
 * CompletableFuture 默认是守护线程  主线程不能过快结束
 * CompletableFuture implements Future<T>, CompletionStage<T>
 * Future  老的
 * CompletionStage  一堆方法
 * CompletableFuture底层默认使用 ForkJoinPool   分支合并池子

 * 从Java8开始引入了CompletableFuture, 它是Future的功能增强版，减少阻塞和轮询
 * 可以传入回调对象，当异步任务完成或者发生异常时，自动调用回调对象的回调方法
 */
public class D1_CompletableFuture了解 { //可以执行复杂的异步任务
    public static void main(String[] args) throws Exception {

//        ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(七个参数);//大家用的
        ExecutorService executorService = Executors.newFixedThreadPool(5);//固定线程


        CompletableFuture<Void> completableFuture1 = new CompletableFuture<>();//不推荐
        //推荐使用 CompletableFuture.runAsync 和 CompletableFuture.supplyAsync

        System.out.println("---------CompletableFuture.runAsync---------------------------------");
        CompletableFuture<Void> completableFuture = //默认是守护线程  主线程不能过快结束
                CompletableFuture.runAsync(() -> {// runAsync 没有返回值
                    System.out.println(Thread.currentThread().getName() + "\t 没有返回值");
                }, executorService);//使用自己的线程池.
        //默认时ForkJoinPool线程池
        System.out.println(completableFuture.get());//runAsync 没有返回值   null

        System.out.println("---------CompletableFuture.supplyAsync---------------------------------");
        CompletableFuture<Integer> integerCompletableFuture =
                CompletableFuture.supplyAsync(() -> {// supplyAsync 有返回值
                    System.out.println(Thread.currentThread().getName() + "\t 有  返  回");
                    return 1024;
                });//默认时ForkJoinPool线程池
        System.out.println(integerCompletableFuture.get());//supplyAsync 有返回值
//        System.out.println(integerCompletableFuture.join());//supplyAsync 有返回值 不抛异常
        executorService.shutdown();//关闭线程池

    }
}
